#include "modbus_device.h"


/* 文件数据临时缓冲区 */
uint8_t file_data[MODBUS_FILE_BUFFER_SIZE];

/* 寄存器数据临时缓冲区 */
uint8_t receive_buffer[MODBUS_REGISTER_BUFFER_SIZE];


/**
  * @brief  Modbus从机用户寄存器注册
  * @note   1个寄存器占2Byte
  * @param  MODBUS_Device: Device对象
  * @retval Modbus从机响应，参见@MODBUS_Error_t
  */
MODBUS_Error_t MODBUS_Device_Register(MODBUS_User_Reg_t *MODBUS_Device)
{
  MODBUS_Error_t modbus_ret = MODBUS_SUCCEED;
  
  modbus_ret = MODBUS_Device->modbus_init(MODBUS_Device);
  
  return modbus_ret;
}


/**
  * @brief  Modbus接收数据处理
  * @note   无
  * @param  MODBUS_Device: Device对象
  * @param  Class: RTU还是TCP
  * @retval Modbus从机响应，参见@MODBUS_Error_t
  */
MODBUS_Error_t MODBUS_Device_Data_Processing(MODBUS_User_Reg_t *MODBUS_Device, MODBUS_Class_t Class)
{
  MODBUS_Error_t modbus_ret = MODBUS_SUCCEED;
  
  if (Class == MODBUS_RTU)
  {
    if (*MODBUS_Device->rx_buffer_rtu->status != MODBUS_TRANSFER_STATUS_END)
    {
      return MODBUS_CRC_ERROR;
    }   
    
    /* 验证CRC */
    if (MODBUS_CRC16(MODBUS_Device->rx_buffer_rtu->data, *MODBUS_Device->rx_buffer_rtu->length) != 0)
    {
      return MODBUS_CRC_ERROR;
    }

    /* 验证从机ID */
    if (MODBUS_Device_ID_Inspect(MODBUS_Device, MODBUS_Device->rx_buffer_rtu->data[0])
      == MODBUS_ID_INSPECT_ERROR)
    {
      return MODBUS_ID_ERROR;
    }

    switch (MODBUS_Device->rx_buffer_rtu->data[1])
    {
      /* 读取线圈位 */
      case 0x01:
        
        break;
      
      /* 读取离散位 */
      case 0x02:
        MODBUS_Device_Read_DiscreteBit(MODBUS_Device, MODBUS_RTU,
          MODBUS_Device->rx_buffer_rtu->data, *MODBUS_Device->rx_buffer_rtu->length);
        break;

      /* 读取保持寄存器 */
      case 0x03:
        MODBUS_Device_Read_HoldReg(MODBUS_Device, MODBUS_RTU,
          MODBUS_Device->rx_buffer_rtu->data, *MODBUS_Device->rx_buffer_rtu->length);
        break;
      
      /* 读取输入寄存器 */
      case 0x04:
        MODBUS_Device_Read_InputReg(MODBUS_Device, MODBUS_RTU,
          MODBUS_Device->rx_buffer_rtu->data, *MODBUS_Device->rx_buffer_rtu->length);
        break;
      
      /* 写单个线圈位 */
      case 0x05:
        
        break;
      
      /* 写单个保持寄存器 */
      case 0x06:
        MODBUS_Device_Write_HoldReg(MODBUS_Device, MODBUS_RTU,
          MODBUS_Device->rx_buffer_rtu->data, *MODBUS_Device->rx_buffer_rtu->length);
        break;
      
      /* 写多个线圈位 */
      case 0x0F:
        
        break;
      
      /* 写多个保持寄存器 */
      case 0x10:
        MODBUS_Device_Write_MultipleHoldReg(MODBUS_Device, MODBUS_RTU,
          MODBUS_Device->rx_buffer_rtu->data, *MODBUS_Device->rx_buffer_rtu->length);
        break;
      
      /* 自定义读文件 */
      case 0x43:
        MODBUS_Device_Read_File(MODBUS_Device, MODBUS_RTU,
          MODBUS_Device->rx_buffer_rtu->data, *MODBUS_Device->rx_buffer_rtu->length);
        break;
      
      /* 自定义写文件 */
      case 0x46:
        MODBUS_Device_Write_File(MODBUS_Device, MODBUS_RTU,
          MODBUS_Device->rx_buffer_rtu->data, *MODBUS_Device->rx_buffer_rtu->length);
        break;
      
      /* 未知的功能码 */
      default:
        MODBUS_Device_Return_Error_Code(MODBUS_Device, MODBUS_RTU,
          MODBUS_Device->rx_buffer_rtu->data[1], MODBUS_FUNC_ERROR);
        modbus_ret = MODBUS_FUNC_ERROR;
        break;
    }
    
    *MODBUS_Device->rx_buffer_rtu->status = MODBUS_TRANSFER_STATUS_IDLE;
    *MODBUS_Device->rx_buffer_rtu->length = 0;
  }
  
  else if (Class == MODBUS_TCP)
  {
    if (*MODBUS_Device->rx_buffer_tcp->status != MODBUS_TRANSFER_STATUS_END)
    {
      return MODBUS_ID_ERROR;
    }  
    
    memcpy(receive_buffer, MODBUS_Device->rx_buffer_tcp->data,
      *MODBUS_Device->rx_buffer_tcp->length);
  
    if ((MODBUS_Device->rx_buffer_tcp->data[2] != 0)
      || (MODBUS_Device->rx_buffer_tcp->data[3] != 0))
    {
      return MODBUS_ID_ERROR;
    }
    
    if (((MODBUS_Device->rx_buffer_tcp->data[4] << 8) | MODBUS_Device->rx_buffer_tcp->data[5])
      != *MODBUS_Device->rx_buffer_tcp->length - 6)
    {
      return MODBUS_ID_ERROR;
    }

    /* 验证从机ID */
    if (MODBUS_Device_ID_Inspect(MODBUS_Device, MODBUS_Device->rx_buffer_tcp->data[6])
      == MODBUS_ID_INSPECT_ERROR)
    {
      return MODBUS_ID_ERROR;
    }

    switch (MODBUS_Device->rx_buffer_tcp->data[7])
    {
      /* 读取线圈位 */
      case 0x01:
        
        break;
      
      /* 读取离散位 */
      case 0x02:
        MODBUS_Device_Read_DiscreteBit(MODBUS_Device, MODBUS_TCP,
          MODBUS_Device->rx_buffer_tcp->data, *MODBUS_Device->rx_buffer_tcp->length);
        break;

      /* 读取保持寄存器 */
      case 0x03:
        MODBUS_Device_Read_HoldReg(MODBUS_Device, MODBUS_TCP,
          &MODBUS_Device->rx_buffer_tcp->data[0], *MODBUS_Device->rx_buffer_tcp->length);
        break;
      
      /* 读取输入寄存器 */
      case 0x04:
        MODBUS_Device_Read_InputReg(MODBUS_Device, MODBUS_TCP,
          &MODBUS_Device->rx_buffer_tcp->data[0], *MODBUS_Device->rx_buffer_tcp->length);
        break;
      
      /* 写单个线圈位 */
      case 0x05:
        
        break;
      
      /* 写单个保持寄存器 */
      case 0x06:
        MODBUS_Device_Write_HoldReg(MODBUS_Device, MODBUS_TCP,
          &MODBUS_Device->rx_buffer_tcp->data[0], *MODBUS_Device->rx_buffer_tcp->length);
        break;
      
      /* 写多个线圈位 */
      case 0x0F:
        
        break;
      
      /* 写多个保持寄存器 */
      case 0x10:
        MODBUS_Device_Write_MultipleHoldReg(MODBUS_Device, MODBUS_TCP,
          &MODBUS_Device->rx_buffer_tcp->data[0], *MODBUS_Device->rx_buffer_tcp->length);
        break;
      
      /* 自定义读文件 */
      case 0x43:
        MODBUS_Device_Read_File(MODBUS_Device, MODBUS_TCP,
          &MODBUS_Device->rx_buffer_tcp->data[0], *MODBUS_Device->rx_buffer_tcp->length);
        break;
      
      /* 自定义写文件 */
      case 0x46:
        MODBUS_Device_Write_File(MODBUS_Device, MODBUS_TCP,
         &MODBUS_Device->rx_buffer_tcp->data[0], *MODBUS_Device->rx_buffer_tcp->length);
        break;
      
      /* 未知的功能码 */
      default:
        MODBUS_Device_Return_Error_Code(MODBUS_Device, MODBUS_TCP,
          MODBUS_Device->rx_buffer_tcp->data[7], MODBUS_FUNC_ERROR);
        modbus_ret = MODBUS_FUNC_ERROR;
        break;
    }
    
    *MODBUS_Device->rx_buffer_tcp->status = MODBUS_TRANSFER_STATUS_IDLE;
    *MODBUS_Device->rx_buffer_tcp->length = 0;
  }
  
  return modbus_ret;
}


/**
  * @brief  Modbus验证从机ID
  * @note   1个寄存器占2Byte
  * @param  MODBUS_Device: Device对象
  * @param  id：需要验证的从机ID
  * @retval Modbus从机响应，参见@MODBUS_ID_Inpect_t
  */
MODBUS_ID_Inpect_t MODBUS_Device_ID_Inspect(MODBUS_User_Reg_t *MODBUS_Device, uint8_t Id)
{
  uint8_t dev_id = *MODBUS_Device->modbus_device_id;
  
  if (Id == dev_id)
  {
    return MODBUS_ID_INSPECT_NATIVE;
  }
  else if (Id == 0x00)
  {
    return MODBUS_ID_INSPECT_ADVER;
  }
  else
  {
    return MODBUS_ID_INSPECT_ERROR;
  }
}


/**
  * @brief  读取离散位
  * @note   无
  * @param  MODBUS_Device: Device对象
  * @param  Class: Modbus数据类型
  * @param  Data: 数据 
  * @param  Size: 数据长度
  * @retval Modbus从机响应，参见@MODBUS_Error_t
  */
MODBUS_Error_t MODBUS_Device_Read_DiscreteBit(MODBUS_User_Reg_t *MODBUS_Device,
  MODBUS_Class_t Class, uint8_t *Data, uint16_t Size)
{
  MODBUS_Error_t modbus_ret = MODBUS_SUCCEED;   // modbus执行结果
  uint16_t bit_addr;                // 地址
  uint16_t bit_count;               // 数量
  uint16_t bit_data_len;            // 数据长度
  uint8_t bit_data[256];            // 数据缓存
  
  if (Class == MODBUS_RTU)
  {
    bit_addr = (Data[2] << 8) | (Data[3]);
    bit_count = (Data[4] << 8) | (Data[5]);
    bit_data_len = bit_count;
    
    /* 地址检查 */
    if (MODBUS_Device_DiscreteBit_Addr_Check(MODBUS_Device, bit_addr, bit_count)
      != MODBUS_SUCCEED)
    {
      MODBUS_Device_Return_Error_Code(MODBUS_Device, Class, Data[1], MODBUS_ADDR_ERROR);
      return MODBUS_ADDR_ERROR;
    }
    else
    {
      /* 用户位 */
      MODBUS_Device->read_discrete_bit(bit_addr, bit_data, bit_count);
      
      /* 准备返回的位数据并最终发送 */
      MODBUS_Device_Return_Read_Bit(MODBUS_Device, 
        Class, Data[1], bit_data, bit_data_len);
      modbus_ret = MODBUS_SUCCEED;
    }
  }
  else if (Class == MODBUS_TCP)
  {
    bit_addr = (Data[8] << 8) | (Data[9]);
    bit_count = (Data[10] << 8) | (Data[11]);
    bit_data_len = bit_count * 2;
    
    /* 地址检查 */
    if (MODBUS_Device_DiscreteBit_Addr_Check(MODBUS_Device, bit_addr, bit_count)
      != MODBUS_SUCCEED)
    {
      MODBUS_Device_Return_Error_Code(MODBUS_Device, Class, Data[7], MODBUS_ADDR_ERROR);
      return MODBUS_ADDR_ERROR;
    }
    else
    {
      /* 用户位 */
      MODBUS_Device->read_discrete_bit(bit_addr, bit_data, bit_count);
      
      /* 准备返回的位数据并最终发送 */
      MODBUS_Device_Return_Read_Bit(MODBUS_Device,
        Class, Data[7], bit_data, bit_data_len);
      modbus_ret = MODBUS_SUCCEED;
    }
  }
  else
  {
    
  }
  
  return modbus_ret;
}


/**
  * @brief  读取输入寄存器
  * @note   1个寄存器占2Byte
  * @param  MODBUS_Device: Device对象
  * @param  Class: Modbus数据类型
  * @param  Data: 数据 
  * @param  Size: 数据长度
  * @retval Modbus从机响应，参见@MODBUS_Error_t
  */
MODBUS_Error_t MODBUS_Device_Read_InputReg(MODBUS_User_Reg_t *MODBUS_Device, 
  MODBUS_Class_t Class, uint8_t *Data, uint8_t Size)
{
  MODBUS_Error_t modbus_ret = MODBUS_SUCCEED;   // modbus执行结果
  uint16_t register_addr;                // 寄存器地址
  uint16_t register_count;               // 寄存器数量
  uint16_t register_data_len;            // 数据长度
  uint8_t register_data[256];            // 数据缓存
  
  if (Class == MODBUS_RTU)
  {
    register_addr = (Data[2] << 8) | (Data[3]);
    register_count = (Data[4] << 8) | (Data[5]);
    register_data_len = register_count * 2;
    
    /* 地址检查 */
    if (MODBUS_Device_InputReg_Addr_Check(MODBUS_Device, register_addr, register_count)
      != MODBUS_SUCCEED)
    {
      MODBUS_Device_Return_Error_Code(MODBUS_Device, Class, Data[1], MODBUS_ADDR_ERROR);
      return MODBUS_ADDR_ERROR;
    }
    else
    {
      /* 用户寄存器 */
      MODBUS_Device->read_input_reg(register_addr, register_data, register_count);
      
      /* 准备返回的寄存器数据并最终发送 */
      MODBUS_Device_Return_Read_Reg(MODBUS_Device, 
        Class, Data[1], register_data, register_data_len);
      modbus_ret = MODBUS_SUCCEED;
    }
  }
  else if (Class == MODBUS_TCP)
  {
    register_addr = (Data[8] << 8) | (Data[9]);
    register_count = (Data[10] << 8) | (Data[11]);
    register_data_len = register_count * 2;
    
    /* 地址检查 */
    if (MODBUS_Device_InputReg_Addr_Check(MODBUS_Device, register_addr, register_count)
      != MODBUS_SUCCEED)
    {
      MODBUS_Device_Return_Error_Code(MODBUS_Device, Class, Data[7], MODBUS_ADDR_ERROR);
      return MODBUS_ADDR_ERROR;
    }
    else
    {
      /* 用户寄存器 */
      MODBUS_Device->read_input_reg(register_addr, register_data, register_count);
      
      /* 准备返回的寄存器数据并最终发送 */
      MODBUS_Device_Return_Read_Reg(MODBUS_Device,
        Class, Data[7], register_data, register_data_len);
      modbus_ret = MODBUS_SUCCEED;
    }
  }
  else
  {
    
  }

  return modbus_ret;
}


/**
  * @brief  读取保持寄存器
  * @note   1个寄存器占2Byte
  * @param  MODBUS_Device: Device对象
  * @param  Class: Modbus数据类型
  * @param  Data: 数据 
  * @param  Size: 数据长度
  * @retval Modbus从机响应，参见@MODBUS_Error_t
  */
MODBUS_Error_t MODBUS_Device_Read_HoldReg(MODBUS_User_Reg_t *MODBUS_Device,
  MODBUS_Class_t Class, uint8_t *Data, uint8_t Size)
{
  MODBUS_Error_t modbus_ret = MODBUS_SUCCEED;    // modbus执行结果
  uint16_t register_addr;                 // 寄存器地址
  uint16_t register_count;                // 寄存器数量
  uint16_t register_data_len;             // 数据长度
  uint8_t register_data[256];             // 数据缓存
  
  if (Class == MODBUS_RTU)
  {
    register_addr = (Data[2] << 8) | (Data[3]);
    register_count = (Data[4] << 8) | (Data[5]);
    register_data_len = register_count * 2;

    /* 检查保持寄存器地址是否合法 */
    if (MODBUS_Device_HoldReg_Addr_Check(MODBUS_Device, register_addr, register_count)
      != MODBUS_SUCCEED)
    {
      /* 非法地址 */
      MODBUS_Device_Return_Error_Code(MODBUS_Device, Class, Data[1], MODBUS_ADDR_ERROR);
      modbus_ret = MODBUS_ADDR_ERROR;
    }
    else
    {
      /* 用户寄存器 */
      MODBUS_Device->read_hold_reg(register_addr, register_data, register_count);
      
      /* 准备返回的寄存器数据并最终发送 */
      MODBUS_Device_Return_Read_Reg(MODBUS_Device, Class, Data[1], register_data, register_data_len);
      modbus_ret = MODBUS_SUCCEED;
    }
  }
  else if (Class == MODBUS_TCP)
  {
    register_addr = (Data[8] << 8) | (Data[9]);
    register_count = (Data[10] << 8) | (Data[11]);
    register_data_len = register_count * 2;

    /* 检查保持寄存器地址是否合法 */
    if (MODBUS_Device_HoldReg_Addr_Check(MODBUS_Device, register_addr, register_count)
      != MODBUS_SUCCEED)
    {
      /* 非法地址 */
      MODBUS_Device_Return_Error_Code(MODBUS_Device, Class, Data[7], MODBUS_ADDR_ERROR);
      modbus_ret = MODBUS_ADDR_ERROR;
    }
    else
    {
      /* 用户寄存器 */
      MODBUS_Device->read_hold_reg(register_addr, register_data, register_count);
      
      /* 准备返回的寄存器数据并最终发送 */
      MODBUS_Device_Return_Read_Reg(MODBUS_Device, Class, Data[7], register_data, register_data_len);
      modbus_ret = MODBUS_SUCCEED;
    }
  }
  else
  {
    
  }

  return modbus_ret;
}


/**
  * @brief  写保持寄存器2个字节
  * @note   1个寄存器占2Byte
  * @param  MODBUS_Device: Device对象
  * @param  Class: Modbus数据类型
  * @param  Data: 数据 
  * @param  Size: 数据长度
  * @retval Modbus从机响应，参见@MODBUS_Error_t
  */
MODBUS_Error_t MODBUS_Device_Write_HoldReg(MODBUS_User_Reg_t *MODBUS_Device,
  MODBUS_Class_t Class, uint8_t *Data, uint8_t Size)
{
  MODBUS_Error_t modbus_ret = MODBUS_SUCCEED;    // modbus执行结果
  uint16_t register_addr;                 // 寄存器地址
  
  if (Class == MODBUS_RTU)
  {
    register_addr = (Data[2] << 8) | (Data[3]);
    
    /* 检查保持寄存器地址是否合法 */
    if (MODBUS_Device_HoldReg_Addr_Check(MODBUS_Device, register_addr, 1)
      != MODBUS_SUCCEED)
    {
      /* 非法地址 */
      MODBUS_Device_Return_Error_Code(MODBUS_Device, Class, Data[1], MODBUS_ADDR_ERROR);
      modbus_ret = MODBUS_ADDR_ERROR;
    }
    else
    {
      /* 用户寄存器 */
      modbus_ret = MODBUS_Device->write_hold_reg(register_addr, &Data[4], 1);
      if (modbus_ret != MODBUS_SUCCEED)
      {
        MODBUS_Device_Return_Error_Code(MODBUS_Device, Class, Data[1], MODBUS_DATA_ERROR);
      }
      else
      {
        /* 准备返回的寄存器数据并最终发送 */
        MODBUS_Device_Return_Write_Reg(MODBUS_Device, Class, &Data[0]);
      }
    }
  }
  else if (Class == MODBUS_TCP)
  {
    register_addr = (Data[8] << 8) | (Data[9]);
    
    /* 检查保持寄存器地址是否合法 */
    if (MODBUS_Device_HoldReg_Addr_Check(MODBUS_Device, register_addr, 1)
      != MODBUS_SUCCEED)
    {
      /* 非法地址 */
      MODBUS_Device_Return_Error_Code(MODBUS_Device, Class, Data[7], MODBUS_ADDR_ERROR);
      modbus_ret = MODBUS_ADDR_ERROR;
    }
    else
    {
      /* 用户寄存器 */
      modbus_ret = MODBUS_Device->write_hold_reg(register_addr, &Data[10], 1);
      if (modbus_ret != MODBUS_SUCCEED)
      {
        MODBUS_Device_Return_Error_Code(MODBUS_Device, Class, Data[1], MODBUS_DATA_ERROR);
      }
      else
      {
        /* 准备返回的寄存器数据并最终发送 */
        MODBUS_Device_Return_Write_Reg(MODBUS_Device, Class, &Data[6]);
      }
    }
  }
  else
  {
    
  }
	
  return modbus_ret;
}



/**
  * @brief  写保持寄存器多个字节
  * @note   1个寄存器占2Byte
  * @param  MODBUS_Device: Device对象
  * @param  Class: Modbus数据类型
  * @param  Data: 数据 
  * @param  Size: 数据长度
  * @retval Modbus从机响应，参见@MODBUS_Error_t
  */
MODBUS_Error_t MODBUS_Device_Write_MultipleHoldReg(MODBUS_User_Reg_t *MODBUS_Device,
  MODBUS_Class_t Class, uint8_t *Data, uint8_t Size)
{
  MODBUS_Error_t modbus_ret = MODBUS_SUCCEED;    // modbus执行结果
  uint16_t register_addr;                 // 寄存器地址
  uint16_t register_count;                // 寄存器数量
  
  if (Class == MODBUS_RTU)
  {
    register_addr = (Data[2] << 8) | (Data[3]);
    register_count = (Data[4] << 8) | (Data[5]);

    /* 检查保持寄存器地址是否合法 */
    if (MODBUS_Device_HoldReg_Addr_Check(MODBUS_Device, register_addr, register_count)
      != MODBUS_SUCCEED)
    {
      /* 非法地址 */
      MODBUS_Device_Return_Error_Code(MODBUS_Device, Class, Data[1], MODBUS_ADDR_ERROR);
      modbus_ret = MODBUS_ADDR_ERROR;
    }
    else
    {
      /* 用户寄存器 */
      modbus_ret = MODBUS_Device->write_hold_reg(register_addr, &Data[7], register_count);
      if (modbus_ret != MODBUS_SUCCEED)
      {
        MODBUS_Device_Return_Error_Code(MODBUS_Device, Class, Data[1], MODBUS_DATA_ERROR);
      }
      else
      {
        /* 准备返回的寄存器数据并最终发送 */
        MODBUS_Device_Return_Write_Reg(MODBUS_Device, Class, &Data[0]);
      }
    }
  }
  else if (Class == MODBUS_TCP)
  {
    register_addr = (Data[8] << 8) | (Data[9]);
    register_count = (Data[10] << 8) | (Data[11]);

    /* 检查保持寄存器地址是否合法 */
    if (MODBUS_Device_HoldReg_Addr_Check(MODBUS_Device, register_addr, register_count)
      != MODBUS_SUCCEED)
    {
      /* 非法地址 */
      MODBUS_Device_Return_Error_Code(MODBUS_Device, Class, Data[7], MODBUS_ADDR_ERROR);
      modbus_ret = MODBUS_ADDR_ERROR;
    }
    else
    {
      /* 用户寄存器 */
      modbus_ret = MODBUS_Device->write_hold_reg(register_addr, &Data[13], register_count);
      if (modbus_ret != MODBUS_SUCCEED)
      {
        MODBUS_Device_Return_Error_Code(MODBUS_Device, Class, Data[1], MODBUS_DATA_ERROR);
      }
      else
      {
        /* 准备返回的寄存器数据并最终发送 */
        MODBUS_Device_Return_Write_Reg(MODBUS_Device, Class, &Data[6]);
      }
    }
  }
  else
  {
    
  }

  return modbus_ret;
}


/**
  * @brief  自定义读文件记录
  * @note   1个寄存器占2Byte
  * @param  MODBUS_Device: Device对象
  * @param  Class: Modbus数据类型
  * @param  Data：读取的数据
  * @param  Size：Modbus一帧数据长度
  * @retval Modbus从机响应，参见@MODBUS_Error_t
  */
MODBUS_Error_t MODBUS_Device_Read_File(MODBUS_User_Reg_t *MODBUS_Device,
  MODBUS_Class_t Class, uint8_t *Data, uint8_t Size)
{
  MODBUS_Error_t modbus_ret = MODBUS_SUCCEED;
  uint16_t file_num, file_packsize;
  uint32_t flie_packnum;
  uint8_t *file_return_pack_data;
  
  if (Class == MODBUS_RTU)
  {
    file_num = (Data[2] << 8) | Data[3];
    flie_packnum = (Data[4] << 24) | (Data[5] << 16) | (Data[6] << 8) | Data[7];
    file_packsize = (Data[8] << 8) | Data[9];
    file_return_pack_data = file_data;
    
    MODBUS_Device->read_user_file(file_num, flie_packnum,
      &file_return_pack_data[10], file_packsize);
    MODBUS_Device_Return_Read_File(MODBUS_Device, MODBUS_RTU,
      0x43, file_num, flie_packnum, file_return_pack_data, file_packsize);
  }
  else if (Class == MODBUS_TCP)
  {
    file_num = (Data[8] << 8) | Data[9];
    flie_packnum = (Data[10] << 24) | (Data[11] << 16) | (Data[12] << 8) | Data[13];
    file_packsize = (Data[14] << 8) | Data[15];
    file_return_pack_data = file_data;
    
    MODBUS_Device->read_user_file(file_num, flie_packnum,
      &file_return_pack_data[16], file_packsize);
    MODBUS_Device_Return_Read_File(MODBUS_Device, MODBUS_RTU,
      0x43, file_num, flie_packnum, file_return_pack_data, file_packsize);
  }
	
  return modbus_ret;
}


/**
  * @brief  自定义写文件记录
  * @note   1个寄存器占2Byte
  * @param  MODBUS_Device: Device对象
  * @param  Class: Modbus数据类型
  * @param  Data：读取的数据
  * @param  Size：Modbus一帧数据长度
  * @retval Modbus从机响应，参见@MODBUS_Error_t
  */
MODBUS_Error_t MODBUS_Device_Write_File(MODBUS_User_Reg_t *MODBUS_Device,
  MODBUS_Class_t Class, uint8_t *Data, uint8_t Size)
{
  MODBUS_Error_t modbus_ret = MODBUS_SUCCEED;
  uint16_t file_num, file_packsize;
  uint32_t flie_packnum;
  uint8_t *file_return_pack_data;
  
  if (Class == MODBUS_RTU)
  {
    file_num = (Data[2] << 8) | Data[3];
    flie_packnum = (Data[4] << 24) | (Data[5] << 16) | (Data[6] << 8) | Data[7];
    file_packsize = (Data[8] << 8) | Data[9];
    file_return_pack_data = &Data[10];
    
    MODBUS_Device->write_user_file(file_num, flie_packnum,
      file_return_pack_data, file_packsize);
    MODBUS_Device_Return_Write_File(MODBUS_Device, MODBUS_RTU,
      0x43, file_num, flie_packnum, file_return_pack_data, file_packsize);
  }
  else if (Class == MODBUS_TCP)
  {
    file_num = (Data[8] << 8) | Data[9];
    flie_packnum = (Data[10] << 24) | (Data[11] << 16) | (Data[12] << 8) | Data[13];
    file_packsize = (Data[14] << 8) | Data[15];
    file_return_pack_data = &Data[16];
    
    MODBUS_Device->write_user_file(file_num, flie_packnum,
      file_return_pack_data, file_packsize);
    MODBUS_Device_Return_Write_File(MODBUS_Device, MODBUS_RTU,
      0x46, file_num, flie_packnum, file_return_pack_data, file_packsize);
  }
  
  return modbus_ret;
}


/**
  * @brief  返回错误代码
  * @note   1个寄存器占2Byte
  * @param  MODBUS_Device: Device对象
  * @param  Class: Modbus数据类型
  * @param  Func: 原功能码
  * @param  Error: 错误类型
  * @retval Modbus从机响应，参见@MODBUS_Error_t
  */
MODBUS_Error_t MODBUS_Device_Return_Error_Code(MODBUS_User_Reg_t *MODBUS_Device,
  MODBUS_Class_t Class, uint8_t Func, uint8_t Error)
{
  uint8_t return_data[16];
  uint16_t crc16;
  
  return_data[6] = *MODBUS_Device->modbus_device_id;  // 第1个字节为ID
  return_data[7] = Func + 0x80;   // 第2个字节为原功能码+0x80，表示有错误
  return_data[8] = Error;         // 第3个字节为错误类型
  
  /* Modbus-TCP字段，RTU不需要 */
  return_data[0] = receive_buffer[0];
  return_data[1] = receive_buffer[1];
  return_data[2] = 0;
  return_data[3] = 0;
  return_data[4] = 0;
  return_data[5] = 3;
  
  crc16 = MODBUS_CRC16(return_data, 3);     // 计算前3个字节的CRC值
  return_data[9]  = (uint8_t)(crc16 >> 8);  // 第4个字节为CRC值高8位
  return_data[10] = (uint8_t)(crc16 >> 0);  // 第5个字节为CRC值低8位

  if (Class == MODBUS_RTU)
  {
    memcpy(MODBUS_Device->tx_buffer_rtu->data, return_data, 6 + 5);
    MODBUS_Device->send_rtu(MODBUS_Device->send_rtu_com,
      &MODBUS_Device->tx_buffer_rtu->data[6], 5);
  }
  else if (Class == MODBUS_TCP)
  {
    memcpy(MODBUS_Device->tx_buffer_tcp->data, return_data, 6 + 5);
    MODBUS_Device->send_tcp(MODBUS_Device->send_tcp_com, 
      &MODBUS_Device->tx_buffer_tcp->data[0], 6 + 5 - 2);
  }
  else
  {
    
  }

  return MODBUS_SUCCEED;
}


/**
  * @brief  返回读位数据
  * @note   16个位占2Byte
  * @param  MODBUS_Device: Device对象
  * @param  Class: Modbus数据类型
  * @param  Func: 原功能码
  * @param  Data: 数据
  * @param  Len: 数据大小
  * @retval Modbus从机响应，参见@MODBUS_Error_t
  */
MODBUS_Error_t MODBUS_Device_Return_Read_Bit(MODBUS_User_Reg_t *MODBUS_Device,
  MODBUS_Class_t Class, uint8_t Func, uint8_t *Data, uint16_t Len)
{
  uint8_t return_data[256 + 32];
  uint16_t crc16;
  uint16_t i;
  uint16_t data_length;

  return_data[6] = *MODBUS_Device->modbus_device_id;  // 第1个字节为ID
  return_data[7] = Func;               // 第2个字节为原功能码
  if (Len < 16)
  {
    return_data[8] = 2;         // 第3个字节为数据长度
  }
  else 
  {
    if ((Len % 16) == 0)
    {
      return_data[8] = Len / 8 + 2;     // 第3个字节为数据长度
    }
    else
    {
      return_data[8] = Len / 8 + 1;     // 第3个字节为数据长度
    }
  }
  
  data_length = return_data[8] + 3;    // 加上前三个字节
  
  for (i = 0; i < data_length; i++)
  {
    return_data[6 + i + 3] = Data[i];
  }
  
  /* Modbus-TCP字段，RTU不需要 */
  return_data[0] = receive_buffer[0];
  return_data[1] = receive_buffer[1];
  return_data[2] = 0; 
  return_data[3] = 0; 
  return_data[4] = (uint8_t)(data_length >> 8); 
  return_data[5] = (uint8_t)(data_length >> 0); 
  
  crc16 = MODBUS_CRC16(&return_data[6], data_length);  // 计算前若干个字节的CRC值
  return_data[6 + Len + 3] = (uint8_t)(crc16 >> 8);    // 填充CRC值高8位
  return_data[6 + Len + 4] = (uint8_t)(crc16 >> 0);    // 填充CRC值低8位
  data_length = data_length + 2;                       // 最后CRC两个字节长度

  if (Class == MODBUS_RTU)
  {
    memcpy(MODBUS_Device->tx_buffer_rtu->data, return_data, data_length + 6);
    MODBUS_Device->send_rtu(MODBUS_Device->send_rtu_com,
      &MODBUS_Device->tx_buffer_rtu->data[6], data_length);
  }
  else if (Class == MODBUS_TCP)
  {
    memcpy(MODBUS_Device->tx_buffer_tcp->data, return_data, data_length + 6);
    MODBUS_Device->send_tcp(MODBUS_Device->send_tcp_com, 
      &MODBUS_Device->tx_buffer_tcp->data[0], 6 + data_length - 2);
  }
  else
  {
    
  }
  
  return MODBUS_SUCCEED;
}


/**
  * @brief  返回读寄存器数据
  * @note   1个寄存器占2Byte
  * @param  MODBUS_Device: Device对象
  * @param  Class: Modbus数据类型
  * @param  Func: 原功能码
  * @param  Data: 数据
  * @param  Len: 数据大小
  * @retval Modbus从机响应，参见@MODBUS_Error_t
  */
MODBUS_Error_t MODBUS_Device_Return_Read_Reg(MODBUS_User_Reg_t *MODBUS_Device, 
  MODBUS_Class_t Class, uint8_t Func, uint8_t *Data, uint16_t Len)
{
  uint8_t return_data[256 + 32];
  uint16_t crc16;
  uint16_t i;
  uint16_t data_length;

  return_data[6] = *MODBUS_Device->modbus_device_id;  // 第1个字节为ID
  return_data[7] = Func;         // 第2个字节为原功能码
  return_data[8] = Len;          // 第3个字节为数据长度
  
  data_length = Len + 3;         // 加上前三个字节
  
  for (i = 0; i < data_length; i++)
  {
    return_data[6 + i + 3] = Data[i];
  }
  
  /* Modbus-TCP字段，RTU不需要 */
  return_data[0] = receive_buffer[0];
  return_data[1] = receive_buffer[1];
  return_data[2] = 0; 
  return_data[3] = 0; 
  return_data[4] = (uint8_t)(data_length >> 8); 
  return_data[5] = (uint8_t)(data_length >> 0); 
  
  crc16 = MODBUS_CRC16(&return_data[6], data_length);  // 计算前若干个字节的CRC值
  return_data[6 + Len + 3] = (uint8_t)(crc16 >> 8);    // 填充CRC值高8位
  return_data[6 + Len + 4] = (uint8_t)(crc16 >> 0);    // 填充CRC值低8位
  data_length = data_length + 2;                       // 最后CRC两个字节长度

  if (Class == MODBUS_RTU)
  {
    memcpy(MODBUS_Device->tx_buffer_rtu->data, return_data, data_length + 6);
    MODBUS_Device->send_rtu(MODBUS_Device->send_rtu_com,
      &MODBUS_Device->tx_buffer_rtu->data[6], data_length);
  }
  else if (Class == MODBUS_TCP)
  {
    memcpy(MODBUS_Device->tx_buffer_tcp->data, return_data, data_length + 6);
    MODBUS_Device->send_tcp(MODBUS_Device->send_tcp_com, 
      &MODBUS_Device->tx_buffer_tcp->data[0], 6 + data_length - 2);
  }
  else
  {
    
  }

  return MODBUS_SUCCEED;
}


/**
  * @brief  返回写寄存器数据
  * @note   1个寄存器占2Byte
  * @param  MODBUS_Device: Device对象
  * @param  Class: Modbus数据类型
  * @param  Data: 数据
  * @retval Modbus从机响应，参见@MODBUS_Error_t
  */
MODBUS_Error_t MODBUS_Device_Return_Write_Reg(MODBUS_User_Reg_t *MODBUS_Device,
  MODBUS_Class_t Class, uint8_t *Data)
{
  uint8_t return_data[16];
  uint16_t crc16;
  uint8_t i;
  
  /* 填充返回数据 */
  for (i = 0; i < 6; i++)
  {
    return_data[6 + i] = Data[i];
  }
  
  /* Modbus-TCP字段，RTU不需要 */
  return_data[0] = receive_buffer[0];
  return_data[1] = receive_buffer[1];
  return_data[2] = 0; 
  return_data[3] = 0; 
  return_data[4] = 0; 
  return_data[5] = 6; 

  crc16 = MODBUS_CRC16(&return_data[6], 6); // 计算前6个字节的CRC值
  return_data[12] = (uint8_t)(crc16 >> 8);  // 填充CRC值高8位
  return_data[13] = (uint8_t)(crc16 >> 0);  // 填充CRC值低8位

  if (Class == MODBUS_RTU)
  {
    memcpy(MODBUS_Device->tx_buffer_rtu->data, return_data, 8 + 6);
    MODBUS_Device->send_rtu(MODBUS_Device->send_rtu_com,
      &MODBUS_Device->tx_buffer_rtu->data[6], 8);
  }
  else if (Class == MODBUS_TCP)
  {
    memcpy(MODBUS_Device->tx_buffer_tcp->data, return_data, 8 + 6);
    MODBUS_Device->send_tcp(MODBUS_Device->send_tcp_com,
      &MODBUS_Device->tx_buffer_tcp->data[0], 6 + 8 - 2);
  }
  else
  {
    
  }

  return MODBUS_SUCCEED;
}


/**
  * @brief  返回写文件记录数据
  * @note   1个寄存器占2Byte
  * @param  MODBUS_Device: Device对象
  * @param  Class: Modbus数据类型
  * @param  Func: 原功能码
  * @param  File_Num: 文件编号
  * @param  Pack_Num: 记录包编号
  * @param  Data: 数据
  * @param  Len: 记录包长度
  * @retval Modbus从机响应，参见@MODBUS_Error_t
  */
MODBUS_Error_t MODBUS_Device_Return_Read_File(MODBUS_User_Reg_t *MODBUS_Device,
  MODBUS_Class_t Class, uint8_t Func,
  uint16_t File_Num, uint32_t Pack_Num, uint8_t *Data, uint16_t Len)
{
  /* 获取读文件数据数组的指针地址 */
  uint8_t *return_data = Data;
  uint16_t crc16;

  return_data[0] = *MODBUS_Device->modbus_device_id;  // 第1个字节为ID
  return_data[1] = Func;                          // 第2个字节为原功能码
  return_data[2] = (uint8_t)(File_Num >> 8);      // 第3 4个字节为文件号
  return_data[3] = (uint8_t)(File_Num >> 0);      // 第3 4个字节为文件号
  return_data[4] = (uint8_t)(Pack_Num >> 24);     // 第5 6 7 8个字节为文件记录包编号
  return_data[5] = (uint8_t)(Pack_Num >> 16);     // 第5 6 7 8个字节为文件记录包编号
  return_data[6] = (uint8_t)(Pack_Num >> 8);      // 第5 6 7 8个字节为文件记录包编号
  return_data[7] = (uint8_t)(Pack_Num >> 0);      // 第5 6 7 8个字节为文件记录包编号
  return_data[8] = (uint8_t)(Len >> 8);           // 第9 10个字节为文件记录包长度
  return_data[9] = (uint8_t)(Len >> 0);           // 第9 10个字节为文件记录包长度

  crc16 = MODBUS_CRC16(return_data, Len + 10);    // 计算前若干个字节的CRC值
  return_data[Len + 10] = (uint8_t)(crc16 >> 8);  // 填充CRC值到最后两个字节
  return_data[Len + 11] = (uint8_t)(crc16 >> 0);  // 填充CRC值到最后两个字节
  Len += 12;																			// 要加上前10个字节和最后CRC两个字节
  
  memcpy(MODBUS_Device->tx_buffer_rtu->data, return_data, Len);

  /* 发送这Len个字节 */
  MODBUS_Device->send_rtu(MODBUS_Device->send_rtu_com,
    MODBUS_Device->tx_buffer_rtu->data, Len);

  return MODBUS_SUCCEED;
}


/**
  * @brief  返回写文件记录数据
  * @note   1个寄存器占2Byte
  * @param  MODBUS_Device: Device对象
  * @param  Class: Modbus数据类型
  * @param  Func: 原功能码
  * @param  File_Num: 文件编号
  * @param  Pack_Num: 记录包编号
  * @param  Data: 数据
  * @param  Len: 记录包长度
  * @retval Modbus从机响应，参见@MODBUS_Error_t
  */
MODBUS_Error_t MODBUS_Device_Return_Write_File(MODBUS_User_Reg_t *MODBUS_Device, 
  MODBUS_Class_t Class, uint8_t Func, 
  uint16_t File_Num, uint32_t Pack_Num, uint8_t *Data, uint16_t Len)
{
  /* 获取读文件数据数组的指针地址 */
  uint8_t *return_data = Data;
  uint16_t crc16;

  return_data[0] = *MODBUS_Device->modbus_device_id;  // 第1个字节为ID
  return_data[1] = Func;                          // 第2个字节为原功能码
  return_data[2] = (uint8_t)(File_Num >> 8);      // 第3 4个字节为文件号
  return_data[3] = (uint8_t)(File_Num >> 0);      // 第3 4个字节为文件号
  return_data[4] = (uint8_t)(Pack_Num >> 24);     // 第5 6 7 8个字节为文件记录包编号
  return_data[5] = (uint8_t)(Pack_Num >> 16);     // 第5 6 7 8个字节为文件记录包编号
  return_data[6] = (uint8_t)(Pack_Num >> 8);      // 第5 6 7 8个字节为文件记录包编号
  return_data[7] = (uint8_t)(Pack_Num >> 0);      // 第5 6 7 8个字节为文件记录包编号
  return_data[8] = (uint8_t)(Len >> 8);           // 第9 10个字节为文件记录包长度
  return_data[9] = (uint8_t)(Len >> 0);           // 第9 10个字节为文件记录包长度

  crc16 = MODBUS_CRC16(return_data, Len + 10);    // 计算前若干个字节的CRC值
  return_data[Len + 10] = (uint8_t)(crc16 >> 8);  // 填充CRC值到最后两个字节
  return_data[Len + 11] = (uint8_t)(crc16 >> 0);  // 填充CRC值到最后两个字节
  Len += 12;																			// 要加上前10个字节和最后CRC两个字节
  
  memcpy(MODBUS_Device->tx_buffer_rtu->data, return_data, Len);

  /* 发送这Len个字节 */
  MODBUS_Device->send_rtu(MODBUS_Device->send_rtu_com, MODBUS_Device->tx_buffer_rtu->data, Len);
  
  return MODBUS_SUCCEED;
}


/**
  * @brief  检查离散位地址是否合法
  * @note   16个位占2Byte
  * @param  MODBUS_Device: Device对象
  * @param  Addr: 数据地址
  * @param  Bit_Count: 位个数
  * @retval 结果，参见@MODBUS_Error_t
  */
MODBUS_Error_t MODBUS_Device_DiscreteBit_Addr_Check(MODBUS_User_Reg_t *MODBUS_Device,
  uint32_t Addr, uint16_t Bit_Count)
{
  /* 一次不能超过252字节 */
  if ((Addr + Bit_Count > (*MODBUS_Device->discrete_bit->start_addr + *MODBUS_Device->discrete_bit->count))
   || (*MODBUS_Device->discrete_bit->start_addr > Addr)
   || (Bit_Count > *MODBUS_Device->discrete_bit->count)
   || (Bit_Count > 126 * 16))
  {
    return MODBUS_ADDR_ERROR;
  }
  else
  {
    return MODBUS_SUCCEED;
  }
}


/**
  * @brief  检查保持寄存器地址是否合法
  * @note   1个寄存器占2Byte
  * @param  MODBUS_Device: Device对象
  * @param  Addr: 数据地址
  * @param  Reg_Count: 寄存器个数
  * @retval 结果，参见@MODBUS_Error_t
  */
MODBUS_Error_t MODBUS_Device_InputReg_Addr_Check(MODBUS_User_Reg_t *MODBUS_Device,
  uint32_t Addr, uint16_t Reg_Count)
{
  /* 一次不能超过252字节 */
  if ((Addr + Reg_Count > (*MODBUS_Device->input_reg->start_addr + *MODBUS_Device->input_reg->count))
   || (*MODBUS_Device->input_reg->start_addr > Addr)
   || (Reg_Count > *MODBUS_Device->input_reg->count)
   || (Reg_Count > 126))
  {
    return MODBUS_ADDR_ERROR;
  }
  else
  {
    return MODBUS_SUCCEED;
  }
}


/**
  * @brief  检查保持寄存器地址是否合法
  * @note   1个寄存器占2Byte
  * @param  MODBUS_Device: Device对象
  * @param  Addr: 数据地址
  * @param  Reg_Count: 寄存器个数
  * @retval 结果，参见@MODBUS_Error_t
  */
MODBUS_Error_t MODBUS_Device_HoldReg_Addr_Check(MODBUS_User_Reg_t *MODBUS_Device,
  uint32_t Addr, uint16_t Reg_Count)
{
  /* 一次不能超过252字节 */
  if ((Addr + Reg_Count > (*MODBUS_Device->hold_reg->start_addr + *MODBUS_Device->hold_reg->count))
   || (*MODBUS_Device->hold_reg->start_addr > Addr)
   || (Reg_Count > *MODBUS_Device->hold_reg->count)
   || (Reg_Count > 126))
  {
    return MODBUS_ADDR_ERROR;
  }
  else
  {
    return MODBUS_SUCCEED;
  }
}


/**
  * @brief  检查读写文件是否合法
  * @note   1个寄存器占2Byte
  * @param  MODBUS_Device: Device对象
  * @param  File_Num: 文件编号
  * @param  Pack_Num: 记录包编号
  * @param  Pack_Len: 记录包长度
  * @retval 结果，参见@MODBUS_Error_t
  */
MODBUS_Error_t MODBUS_Device_File_Check(MODBUS_User_Reg_t *MODBUS_Device, 
  uint32_t File_Num, uint32_t Pack_Num, uint16_t Pack_Len)
{
  return MODBUS_SUCCEED;
}


